from loguru import logger

from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from django_redis import get_redis_connection
from utils.captcha import captcha
from django.contrib.auth.forms import UserCreationForm

from ..models import Accounts


class SignupForm(UserCreationForm):
    avatar = forms.ImageField(required=False)

    class Meta(UserCreationForm.Meta):
        fields = ("username", "email", "password1", "password2")

    def save(self, commit=True):
        user = super().save(commit=False)
        user.email = self.cleaned_data["email"]
        if commit:
            user.save()
            # 创建关联的Profile对象
            Accounts.objects.create(
                user=user,
                # mobile=self.cleaned_data['mobile'],
                avatar=self.cleaned_data["avatar"],
            )
        return user


class LoginForm(forms.Form):
    # 生成html标签, widget:添加标签类型， attrs添加属性, required: 字段是否必传,默认为True
    username = forms.CharField(
        label="用户名",
        min_length=6,  # 最小长度
        max_length=18,  # 最大长度
        initial="Tester",  # 设置默认值
        widget=forms.TextInput(attrs={"class": "input-group", "placeholder": "用户名"}),
    )
    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(
            attrs={"class": "input-group", "placeholder": "用户密码"}
        ),
    )

    captcha = forms.CharField(
        label="验证码",
        validators=[RegexValidator(r"^\w{4}+$", "验证码必须是数字字母")],  # 正则表达式校验规则
        widget=forms.TextInput(
            attrs={
                "id": "captcha-input",
                "name": "captcha",
                "pattern": "\w{4}",
                "placeholder": "验证码",
            }
        ),
    )
    captcha_key = forms.CharField(widget=forms.TextInput())

    def clean_captcha(self):
        """验证验证码"""

        captcha_key = self.cleaned_data.get("captcha_key", "")
        captcha_code = self.cleaned_data.get("captcha", "")

        if not captcha_key or not captcha:
            return ValidationError({"status": "error", "message": "参数缺失"}, code=400)

        if captcha.validate_captcha(captcha_key, captcha_code):
            logger.debug("Captcha verification successful")
            return captcha_key

        else:
            raise ValidationError("验证码已过期或失效")


class SmsLoginForm(forms.Form):
    # role = forms.ChoiceField(
    #     label='角色',
    #     required=True,  # 字段是否必传
    #     choices=(('1', '管理员'), ('2', '客户')),
    #     widget=forms.Select(attrs={'class': 'form-control'})
    # )

    # 生成html标签, widget:添加标签类型， attrs添加属性, required: 字段是否必传,默认为True
    mobile = forms.CharField(
        label="手机号",
        min_length=11,  # 最小长度
        max_length=11,  # 最大长度
        initial="18888888888",  # 设置默认值
        widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "手机号"}),
    )
    code = forms.CharField(
        label="短信验证码",
        validators=[RegexValidator(r"^[0-9]+$", "验证码必须是数字")],  # 正则表达式校验规则
        widget=forms.TextInput(attrs={"class": "form-control", "placeholder": "短信验证码"}),
    )

    def clean_mobile(self):
        role = self.cleaned_data.get("role")
        mobile = self.cleaned_data.get("mobile")
        if not role:
            return mobile
        if role == "1":
            user_object = Accounts.objects.filter(active=1, mobile=mobile).first()
        else:
            user_object = Accounts.objects.filter(active=1, mobile=mobile).first()

        if not user_object:
            logger.debug(f"查询用户失败:::{mobile}-{role}")
            raise ValidationError("手机号不存在")
        return mobile

    def clean_code(self):
        mobile = self.cleaned_data.get("mobile")
        code = self.cleaned_data.get("code")
        if not mobile:
            return code
        conn = get_redis_connection("default")
        cache_code = conn.get(mobile)
        if not cache_code:
            logger.warning(f"验证码已失效")
            raise ValidationError("短信验证码已失效")
        logger.info(f"验证码::: {code}, 缓存验证码::: {cache_code}")
        if code != cache_code.decode("utf8"):
            logger.debug("验证不一致，验证失败")
            raise ValidationError("短信验证码错误")
        return code


class MobileForm(forms.Form):
    mobile = forms.CharField(
        label="手机号", validators=[RegexValidator(r"^1[358]\d{9}$", "手机号格式错误")]
    )

    role = forms.ChoiceField(
        label="角色",
        required=True,  # 字段是否必传
        choices=(("1", "管理员"), ("2", "客户")),
        widget=forms.Select(attrs={"class": "form-control"}),
    )

    def clean_mobile(self):
        if len(self.cleaned_data.get("mobile")) != 11:
            raise forms.ValidationError("手机号长度错误")

        role = self.cleaned_data.get("role")
        mobile = self.cleaned_data.get("mobile")
        if not role:
            return mobile
        if role == "1":
            exists = Accounts.objects.filter(active=1, mobile=mobile).exists()
        else:
            exists = Accounts.objects.filter(active=1, mobile=mobile).exists()
        if not exists:
            raise ValidationError("手机号不存在")
        return mobile
